import React from 'react';
import {observer, observable, action} from 'mobx.collection';
import uuidv4 from 'uuid/v4';
import {REQUEST_STATE} from "fetchState";
import FetchController from "fetch";
import {notify} from "components/state/toast";
import {formatClassList} from "auxiliaries/extends/format";
import {Download, Hint} from "components/state/data-load";
import ReactLoading from "react-loading";

@observer
class CommonListPage extends React.Component {
    @observable PageList = [];
    @observable PageStatus = 'loading';
    Request = {};
    PageCount = 10;

    #Random = uuidv4();
    #CurrentPromise;

    async reset() {
        this.PageCount = 10;
        this.PageList = [];
        this.PageStatus = 'loading';
        await this.updateList();

    }

    @action
    async updateList(props = this.props) {
        let {
            controller,
            params = {},
            count = this.PageCount,
        } = props || {};

        props?.onLoadBefore?.(this);

        if (this.#CurrentPromise) {
            FetchController.close(this.#CurrentPromise);
        }
        this.#CurrentPromise = controller(params, this.PageList.length, count);
        let {CODE, DATA, STATUS, DETAILS, MESSAGE, ORIGIN: {Total}} = await this.#CurrentPromise;
        this.Request = {CODE, DATA, STATUS, DETAILS, MESSAGE, TOTAL: Total};
        if (CODE === REQUEST_STATE.CANCEL) {
            return false;
        }

        if (STATUS === 0) {
            this.PageList = this.PageList.concat(DATA);
        } else {
            notify(DETAILS || MESSAGE);
        }

        if (this.PageList.length === 0) {
            this.PageStatus = 'non-data';
        } else if (!DATA || DATA.length === 0 || this.PageList.length % count) {
            this.PageStatus = 'end';
        } else {
            this.PageStatus = 'finish';
        }

        props?.onLoadAfter?.(this);
    }

    componentDidMount() {
        this.PageCount = 10;
        this.PageStatus = 'loading';

        this.updateList();
    }

    componentWillReceiveProps(nextProps) {

        let leftKeys = Object.keys(this.props.params || {});
        let rightKeys = Object.keys(nextProps.params || {});

        if (leftKeys.length !== rightKeys.length) {
            this.PageCount = 10;
            this.PageList = [];
            this.PageStatus = 'loading';
            this.updateList(nextProps);
        } else {
            let hasAbnormal = leftKeys.filter(key => this.props.params[key] !== nextProps.params[key]).length;

            if (!!hasAbnormal) {
                this.PageCount = 10;
                this.PageList = [];
                this.PageStatus = 'loading';
                this.updateList(nextProps);
            }
        }

    }

    async onDownload() {
        await this.updateList();
    }

    componentWillUnmount() {
        this.setState = function () {
        };
    }

    onSwipePage() {
        switch (this.PageStatus) {
            case 'error':
                return <Hint onClick={this.onDownload.bind(this)}>服务器繁忙，请尝试点击重新加载！</Hint>;
            case 'finish':
                return <></>;
            case 'loading':
                return (
                    <div className={"common-loading flex-start"}>
                        <ReactLoading className={"load"} type={"spin"} color="#ddd"/>
                    </div>
                );
            case 'end':
                return <Hint>已经到底部了</Hint>;
            case 'non-data':
                return <Hint>{this.props.nonDataText || '暂无列表'}</Hint>;
            default:
                return <></>;
        }
    }

    render() {
        let {
            component: dataComponent,
            children,
            render,
            convert,
            className,
        } = this.props;

        return (
            <>
                <div className={["--page-list"].concat(formatClassList(className)).join(' ')}>
                    {
                        this.PageList.map((x, i) => {
                            let item = x;
                            if (typeof convert === 'function') {
                                item = convert(item);
                            }

                            if (dataComponent) {
                                return React.createElement(dataComponent, {
                                    item: item,
                                    key: 'dataComponent-' + this.#Random + i
                                });
                            } else if (children) {
                                return children(item);
                            } else if (render) {
                                return render(item);
                            }
                            return <></>;
                        })
                    }
                    {this.onSwipePage()}
                </div>

                <Download onDownload={() => this.onDownload()} onDownloadBefore={() => this.PageStatus === "finish"}/>
            </>
        );
    }
}

@observer
class CommonResultListPage extends React.Component {
    #CommonListRef;
    @observable PageCount = 0;
    @observable PageStatus = 'loading';

    // componentDidMount() {
    //     this.PageList = this.CommonListRef.PageList;
    // }

    // componentWillReceiveProps(nextProps) {
    //     console.log(nextProps);
    // }

    onLoadBefore() {
        this.PageStatus = 'loading';
    }

    onLoadAfter() {
        this.PageCount = this.#CommonListRef?.PageList.length;
        this.PageStatus = this.#CommonListRef?.PageStatus;
    }

    render() {
        return (
            <>
                {
                    this.PageStatus === 'loading' ? null :
                        <p className={"font-size-30"}>共有相关结果{this.PageCount}条</p>
                }

                <CommonListPage {...this.props} ref={_ => this.#CommonListRef = _}
                                onLoadBefore={this.onLoadBefore.bind(this)}
                                onLoadAfter={this.onLoadAfter.bind(this)}/>
            </>
        );
    }
}

export {
    CommonResultListPage
};
export default CommonListPage;